/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.octopeer.network;

import java.net.Socket;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Observable;

/**
 *
 * @author andria
 */
public class Talker extends Observable implements Runnable {
    /**
     * Uses to connect to the server 
     */
    private Socket socket;

    /**
     * For reading input from server. 
     */
    private BufferedReader br;

    /**
     * For writing output to server. 
     */
    private PrintWriter pw;

    /**
     * Status of client. 
     */
    private boolean connected;

    /**
     * Port number of server
     */
    private int port=5555; //default port

    /**
     * Host Name or IP address in String form
     */
    private String hostName="localhost";//default host name

    /**
     * 
     */
    public Talker() {
        connected = false;
    }
    
    /**
     * 
     * @param port
     */
    public Talker(int port) {
        this.port = port;
    }
    
    public Talker(String hostName, int port) {
        this.hostName = hostName;
        this.port = port;
    }
    
    /**
     * 
     * @param hostName
     * @param port
     * @throws java.io.IOException
     */
    public void connect(String hostName, int port) throws IOException {
        if(!connected) {
            this.hostName = hostName;
            this.port = port;
            socket = new Socket(hostName,port);
            //get I/O from socket
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            pw = new PrintWriter(socket.getOutputStream(),true);

            connected = true;
            //initiate reading from server...
            Thread t = new Thread(this);
            t.start(); //will call run method of this class
        }
    }

    /**
     * 
     * @param msg
     * @throws java.io.IOException
     */
    public void sendMessage(String msg) throws IOException {
        if(connected) {
            pw.println(msg);
        } else {
            throw new IOException("Not connected to server");
        }
    }

    /**
     * 
     */
    public void disconnect() {
        if(socket != null && connected) {
            try {
                socket.close();
            } catch(IOException ioe) {
                //unable to close, nothing to do...
            } finally {
                this.connected = false;
            }
        }
    }

    /**
     * 
     */
    public void run() {
        String msg = ""; //holds the msg recieved from server
        try {
            while(connected && (msg = br.readLine())!= null) {
                System.out.println(msg);
                //notify observers//
                this.setChanged();
                //notify+send out recieved msg to Observers
                this.notifyObservers(msg);
            }
        } catch(IOException ioe) { 
            //
        } finally { 
            connected = false; 
        }
    }
    
    /**
     * 
     * @return
     */
    public boolean isConnected() {
        return connected;
    }

    /**
     * 
     * @return
     */
    public int getPort(){
        return port;
    }

    /**
     * 
     * @param port
     */
    public void setPort(int port){
        this.port = port;
    }

    /**
     * 
     * @return
     */
    public String getHostName(){
        return hostName;
    }

    /**
     * 
     * @param hostName
     */
    public void setHostName(String hostName){
        this.hostName = hostName;
    }
    
//    public static void main(String[] args) throws IOException {
//        Talker c = new Talker();
//        c.connect("localhost",9090);
//        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        String msg = "";
//        while(!msg.equalsIgnoreCase("quit")) {
//            msg = br.readLine();
//            c.sendMessage(msg);
//        }
//        c.disconnect();
//    }
}
